package com.sip.stream.utils.zfy.encoder;

import android.media.MediaCodec;
import android.media.MediaCodecList;
import android.media.MediaCrypto;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;

import com.sip.stream.media.ZFYMediaManager;
import com.sip.stream.utils.zfy.GSMediaSampleData;
import com.sip.stream.utils.zfy.consumer.IGSAudioEncoderConsumer;
import com.sip.stream.utils.zfy.consumer.IGSMediaObserver;
import com.sip.stream.utils.zfy.consumer.IGSWAVConsumer;

import java.io.IOException;
import java.nio.ByteBuffer;

public class GSAACEncoder extends AbstractMediaCodecEncoder implements IGSAudioEncoder {
    private static final String TAG = "GSACCEncoder";

    private int TIME_OUT = 0;
    private IGSAudioEncoderConsumer listener;
    private int sampleRate;
    private IGSMediaObserver<IGSWAVConsumer> wavConsumerObserver;

    @Override
    public void onStop(IGSAudioEncoderConsumer iGSAudioEncoderConsumer) {
    }

    @Override
    public void removeLisener(IGSAudioEncoderConsumer iGSAudioEncoderConsumer) {
    }

    public GSAACEncoder(int sampleRate, int channelCount, int bitrate) {
        this.sampleRate = sampleRate;
        setUpMediaCodec(sampleRate, channelCount, bitrate);
    }

    private boolean setUpMediaCodec(int sampleRate, int channelCount, int bitrate) {
        MediaFormat createAudioFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", sampleRate, channelCount);
        createAudioFormat.setInteger("aac-profile", 2);
        createAudioFormat.setInteger("bitrate", bitrate);
        createAudioFormat.setInteger("channel-count", channelCount);
        createAudioFormat.setInteger("frame-rate", 25);
        createAudioFormat.setInteger("i-frame-interval", 1);
        createAudioFormat.setInteger("max-input-size", 102400);
        if (channelCount > 1) {
            createAudioFormat.setInteger("channel-mask", 12);
        } else {
            createAudioFormat.setInteger("channel-mask", 16);
        }
        if (new MediaCodecList(1).findEncoderForFormat(createAudioFormat) == null) {
            Log.e(TAG, "未找到音频编码器");
            return false;
        }
        try {
            this.mediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
            this.mediaCodec.configure(createAudioFormat, (Surface) null, (MediaCrypto) null, 1);
            this.mediaCodec.start();
            startEncode();
            Log.i(TAG, "创建ACC编码器成功");
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void startEncode() {
        MediaCodec mediaCodec = this.mediaCodec;
    }

    @Override
    public void stopEncode() {
        IGSMediaObserver<IGSWAVConsumer> iGSMediaObserver = this.wavConsumerObserver;
        if (iGSMediaObserver != null) {
            iGSMediaObserver.onStop(this);
        }
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        bufferInfo.flags = 4;
        encodeAudioSuccess(null, bufferInfo, 0);
        this.isStop = true;
        encode(null, ZFYMediaManager.getInstance().getPresentationTimeUs(), true);
    }

    @Override
    public void onAudioStream(byte[] bArr, long j) {
        encode(bArr, j, false);
    }

    @Override
    public void addObserver(IGSMediaObserver<IGSWAVConsumer> iGSMediaObserver) {
        this.wavConsumerObserver = iGSMediaObserver;
    }

    public boolean encode(byte[] bArr, long j, boolean z)
    {
        try {
            int dequeueInputBuffer = this.mediaCodec.dequeueInputBuffer(this.TIME_OUT);
            if (dequeueInputBuffer >= 0) {
                if (z) {
                    this.mediaCodec.queueInputBuffer(dequeueInputBuffer, 0, 0, j, 4);
                    Log.i(TAG, "queueInputBuffer BUFFER_FLAG_END_OF_STREAM");
                } else {
                    ByteBuffer inputBuffer = this.mediaCodec.getInputBuffer(dequeueInputBuffer);
                    inputBuffer.clear();
                    int length = bArr.length;
                    inputBuffer.limit(length);
                    inputBuffer.put(bArr, 0, length);
                    this.mediaCodec.queueInputBuffer(dequeueInputBuffer, 0, length, j, 0);
                }
            }
            while (true) {
                MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                int dequeueOutputBuffer = this.mediaCodec.dequeueOutputBuffer(bufferInfo, this.TIME_OUT);
                if (bufferInfo.flags != 2) {
                    if (bufferInfo.flags == 4) {
                        Log.i(TAG, "flags == BUFFER_FLAG_END_OF_STREAM");
                        stopMediaCodec();
                        return true;
                    } else if (dequeueOutputBuffer >= 0) {
                        ByteBuffer outputBuffer = this.mediaCodec.getOutputBuffer(dequeueOutputBuffer);
                        outputBuffer.position(bufferInfo.offset);
                        outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
                        if (bufferInfo.size > 0) {
                            encodeAudioSuccess(copyDirectByteBuffer(outputBuffer), bufferInfo, dequeueOutputBuffer);
                        }
                        this.mediaCodec.releaseOutputBuffer(dequeueOutputBuffer, false);
                    } else if (dequeueOutputBuffer != -2) {
                        return true;
                    } else {
                        setOutputFormat();
                    }
                }
            }
        } catch (Exception unused) {
            return true;
        }
    }

    @Override
    public void addLisener(IGSAudioEncoderConsumer iGSAudioEncoderConsumer) {
        IGSAudioEncoderConsumer iGSAudioEncoderConsumer2;
        this.listener = iGSAudioEncoderConsumer;
        if (this.cacheOutputFormate == null || (iGSAudioEncoderConsumer2 = this.listener) == null) {
            return;
        }
        iGSAudioEncoderConsumer2.setOutputFormat(this.cacheOutputFormate);
    }

    public void setOutputFormat() {
        this.cacheOutputFormate = this.mediaCodec.getOutputFormat();
        if (this.listener != null) {
            this.listener.setOutputFormat(this.cacheOutputFormate);
        }
    }

    public void encodeAudioSuccess(ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo, int i) {
        if (this.listener != null) {
            this.listener.encodeAudioSuccess(GSMediaSampleData.createAudioSampleData(byteBuffer, bufferInfo));
        }
        if (bufferInfo.flags == 4) {
            this.listener = null;
            this.mediaCodec.stop();
            this.mediaCodec.release();
            Log.i(TAG, "aac编码器  mediaCodec.stop() release 关闭");
            this.mediaCodec = null;
        }
    }
}
